P0 // P=Philospher
f0 f1 // f=fork
P3 P1 // Philopsher[i] will pick up fork[i], fork[i+1]
f3 f2
P2
Steps:
1. Create 4 forks. vec[Arc<Mutex>]
2. Create 4 Philosophers (ie 4 Philospher structs in for loop)
3. Philopsher[i] gets fork[i], fork[i+1]
4. Write eat() function, which uses Arc
|
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
struct Fork;
struct Philosopher {
name: String,
left_fork: Arc>,
right_fork: Arc>,
}
impl Philosopher {
fn eat(&self) {
println!("{} is trying to eat", &self.name);
let _left = self.left_fork.lock().unwrap();
let _right = self.right_fork.lock().unwrap();
println!("{} is eating...", &self.name);
thread::sleep(Duration::from_millis(10));
}
}
static PHILOSOPHERS: &[&str] =
&["Ph1", "Ph2", "Ph3", "Ph4"];
fn main() {
let mut handles = vec![]; // Store thread handles
let mut forks = vec![];
for _ in 0..PHILOSOPHERS.len() {
forks.push(Arc::new(Mutex::new(Fork)));
}
for i in 0..PHILOSOPHERS.len() {
let mut left_fork = Arc::clone(&forks[i]);
let mut right_fork = Arc::clone(&forks[(i + 1) % forks.len()]);
// To avoid a deadlock, we have to break the symmetry
// somewhere. This will swap the forks without deinitializing
// either of them.
if i == forks.len() - 1 {
std::mem::swap(&mut left_fork, &mut right_fork);
}
// Philospher=i gets ready
let philosopher = Philosopher {
name: PHILOSOPHERS[i].to_string(),
left_fork,
right_fork,
};
let handle = thread::spawn(move || {
for _ in 0..10 {
philosopher.eat();
}
});
handles.push(handle); // Store the handle
}
for handle in handles {
handle.join().unwrap();
}
}
|